#include <cstring>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <Eigen/IterativeLinearSolvers>
#include <Eigen/Core>
#include <util/os.hpp>

#include "PencilDrawing.hpp"

using namespace std;
using namespace cv;
using namespace kikyo;

static void help() {
	cout << "Usage: Kikyo [-f/-d] [-g/-c] imgBasePath patternPath outputPath" << endl
		<< "-d means that imgBasePath is a directory path, -f means that imageBasePath is a image file path." << endl
		<< "-g means to load iamge by the gray image method, -c means color iamge." << endl
		<< "Eg: Kikyo -d ./PencilDrawing/data ./PencilDrawing/pencils/pencil0.jpg ./results" << endl;
}

static void drawing(const PencilDrawing& pencil, const string& filePath, const string& patternPath, 
	const string& outputPath, int flag) {
	Mat img = imread(filePath, flag);
	Mat pattern = imread(patternPath, flag);
	Mat pencilDrawing;
	pencil(img, pattern, pencilDrawing);
	string basename;
	OS::basename(filePath, basename);
	imshow("PencilDrawing", pencilDrawing);
	waitKey(0);
	imwrite(outputPath + OS::getSeparator() + basename, pencilDrawing);
}

int main(int argc, char* argv[]) {
	const char* errImg = "Please using Kikyo -h to get help.";

	string imgBasePath;
	string patternPath;
	string outputPath;
	vector<string> allImages;
	PencilDrawing pencil;

	if (argc == 2) {
		if (strlen(argv[1]) == 2) {
			if (argv[1][0] == '-' && argv[1][1] == 'h')
				help();
			else
				cerr << errImg << endl;
		}
	} else if (argc == 6) {
		imgBasePath = argv[3];
		patternPath = argv[4];
		outputPath = argv[5];
		if (strlen(argv[1]) == 2 && argv[1][1] == 'f') {
			Mat img, pattern;
			if (strlen(argv[2]) == 2 && argv[2][1] == 'g') {
				drawing(pencil, imgBasePath, patternPath, outputPath, CV_LOAD_IMAGE_GRAYSCALE);
			} else if (strlen(argv[2]) == 2 && argv[2][1] == 'c') {
				drawing(pencil, imgBasePath, patternPath, outputPath, CV_LOAD_IMAGE_COLOR);
			} else
				cerr << errImg << endl;
		} else if (strlen(argv[1]) == 2 && argv[1][1] == 'd') {
			vector<string> imgPath;
			OS::dir(imgBasePath, imgPath, OS::DIR_ONLY_FILES);
			if (strlen(argv[2]) == 2 && argv[2][1] == 'g') {
				for (auto str : imgPath)
					drawing(pencil, imgBasePath + "/" + str, patternPath, outputPath, CV_LOAD_IMAGE_GRAYSCALE);
			}
			else if (strlen(argv[2]) == 2 && argv[2][1] == 'c') {
				string filePath = imgBasePath.c_str();
				for (auto str : imgPath)
					drawing(pencil, imgBasePath + "/" + str, patternPath, outputPath, CV_LOAD_IMAGE_COLOR);
			}
			else
				cerr << errImg << endl;
		} else {
			cerr << errImg << endl;
		}
	} else {
		cerr << errImg << endl;
	}

	std::system("pause");
	return 0;
}

